package org.squabble.service;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.squabble.dao.CommentDAO;
import org.squabble.domain.Account;
import org.squabble.domain.Comment;
import org.squabble.domain.CommentTag;
import org.squabble.domain.Flag;
import org.squabble.domain.Tag;

@Service
public class CommentService {

	@Autowired
	TagService tagService;

	@Autowired
	FlagService flagService;
	
	@Autowired
	CommentDAO commentDAO;

	@Transactional(readOnly = true)
	public List<Comment> getComments() {
		return commentDAO.getComments();
	}

	@Transactional(readOnly = true)
	public Comment getComment(Long remarkId) {
		return commentDAO.getComment(remarkId);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void postComment(Long articleId, Long parentId, String title,
			String text, String tags, List<Long> flags, Account account) {
		Date now = new Date();
		Comment comment = new Comment();
		comment.setSourceDate(now);
		comment.setAccount(account);
		comment.setText(text);
		comment.setTitle(title);
		Set<CommentTag> commentTags = new HashSet<CommentTag>();
		Set<Tag> tagSet = tagService.saveTags(tags);
		for (Tag tag : tagSet) {
			CommentTag ct = new CommentTag();
			ct.setAccount(account);
			ct.setRemark(comment);
			ct.setTag(tag);
			ct.setSourceDate(now);
			commentTags.add(ct);
		}
		comment.setCommentTags(commentTags);
		if (parentId != null) {
			Comment parent = this.getComment(parentId);
			comment.setParent(parent);
			if (parent.getRoot() == null) {
				comment.setRoot(parent);
			} else {
				comment.setRoot(parent.getRoot());
			}
			parent.setLastReplyDate(now);
			commentDAO.save(parent);
		}
		Set<Flag> flagSet = comment.getFlags();
		for(Long flagId : flags) {
			Flag f = flagService.loadFlag(flagId);
			flagSet.add(f);
		}
		comment.setFlags(flagSet);
		commentDAO.save(comment);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void updateCommentTags(Long commentId, String tags, Account account) {
		Date now = new Date();
		Comment comment = getComment(commentId);
		Set<CommentTag> commentTags = comment.getCommentTags();
		Set<Tag> tagSet = tagService.saveTags(tags);
		for (Tag tag : tagSet) {
			CommentTag ct = new CommentTag();
			ct.setAccount(account);
			ct.setRemark(comment);
			ct.setTag(tag);
			ct.setSourceDate(now);
			if (isNewTag(ct, commentTags)) {
				commentTags.add(ct);
			}
		}
		comment.setCommentTags(commentTags);
		commentDAO.save(comment);
	}

	public boolean isNewTag(CommentTag ct, Set<CommentTag> commentTags) {
		for (CommentTag commentTag : commentTags) {
			Account a1 = commentTag.getAccount();
			Account a2 = ct.getAccount();
			Tag t1 = commentTag.getTag();
			Tag t2 = ct.getTag();
			Comment c1 = commentTag.getComment();
			Comment c2 = ct.getComment();
			if(a1.equals(a2) && t1.equals(t2) && c1.equals(c2)) {
				return false;
			}
		}
		return true;
	}
}
